<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="Seata" />
	<meta name="description" content="Api Guide." />
	<!-- 网页标签标题 -->
	<title>Api Guide</title>
  <link rel="shortcut icon" href="/img/seata_logo_small.jpeg"/>
	<link rel="stylesheet" href="/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/en-us/index.html"><img class="logo" src="//img.alicdn.com/tfs/TB1gqL1w4D1gK0jSZFyXXciOVXa-1497-401.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">中</span><div class="header-menu"><img class="header-menu-toggle" src="https://img.alicdn.com/tfs/TB14eEmw7P2gK0jSZPxXXacQpXa-38-32.png"/><ul><li class="menu-item menu-item-normal"><a href="/en-us/index.html" target="_self">HOME</a></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="/en-us/docs/overview/what-is-seata.html" target="_self">DOCS</a></li><li class="menu-item menu-item-normal"><a href="/en-us/docs/developers/developers_dev.html" target="_self">DEVELOPERS</a></li><li class="menu-item menu-item-normal"><a href="/en-us/blog/index.html" target="_self">BLOG</a></li><li class="menu-item menu-item-normal"><a href="/en-us/community/index.html" target="_self">COMMUNITY</a></li><li class="menu-item menu-item-normal"><a href="/en-us/blog/download.html" target="_self">DOWNLOAD</a></li></ul></div></div></header><div class="bar"><div class="bar-body"><img src="https://img.alicdn.com/tfs/TB1cm8nJwDqK1RjSZSyXXaxEVXa-160-160.png" class="front-img"/><span>Documentation</span><img src="https://img.alicdn.com/tfs/TB1cm8nJwDqK1RjSZSyXXaxEVXa-160-160.png" class="back-img"/></div></div><section class="content-section"><div class="sidemenu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Overview</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/overview/what-is-seata.html" target="_self">What is Seata?</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/overview/terminology.html" target="_self">Terminology</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/overview/faq.html" target="_self">FAQ</a></li></ul></li><li class="menu-item menu-item-level-1"><span>User Doc</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/user/quickstart.html" target="_self">Quick Start</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/user/api.html" target="_self">API Guide</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/user/microservice.html" target="_self">Microservices Framework Supports</a></li></ul></li><li class="menu-item menu-item-level-1"><span>Developer Guide</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><span>Transaction Mode<img style="transform:rotate(-90deg)" class="menu-toggle" src="https://img.alicdn.com/tfs/TB15.Ilw2b2gK0jSZK9XXaEgFXa-26-16.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/en-us/docs/dev/mode/at-mode.html" target="_self">Seata AT mode</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/dev/mode/tcc-mode.html" target="_self">Seata TCC mode</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/dev/mode/saga-mode.html" target="_self">Seata Saga mode</a></li></ul></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/dev/seata-mertics.html" target="_self">Metrics design</a></li></ul></li><li class="menu-item menu-item-level-1"><span>Ops Guide</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/en-us/docs/ops/multi-configuration-isolation.html" target="_self">Configuration Isolation</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><span>Deploy<img style="transform:rotate(-90deg)" class="menu-toggle" src="https://img.alicdn.com/tfs/TB15.Ilw2b2gK0jSZK9XXaEgFXa-26-16.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/en-us/docs/ops/deploy-server.html" target="_self">Deploy Directly</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/ops/deploy-by-docker.html" target="_self">Deploy by Docker</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/ops/deploy-by-kubernetes.html" target="_self">Deploy by Kubernetes</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/ops/deploy-by-helm.html" target="_self">Deploy by Helm</a></li><li class="menu-item menu-item-level-3"><a href="/en-us/docs/ops/deploy-ha.html" target="_self">Deploy in High Available Usage</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body"><h1>1. Overview</h1>
<p>Seata API is devided into 2 categories: High-Level API and Low-Level API</p>
<ul>
<li><strong>High-Level API</strong> : Used for defining and controlling transaction boundary, and querying transaction status.</li>
<li><strong>Low-Level API</strong> : Used for controlling the propagation of transaction context.</li>
</ul>
<h1>2. High-Level API</h1>
<h2>2.1 GlobalTransaction</h2>
<p>GlobalTransaction class contains methods about begin transaction, commit transaction, rollback transaction and get status of transaction and so on.</p>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">GlobalTransaction</span> </span>{

    <span class="hljs-comment">/**
     * Begin a global transaction(Use default transaction name and timeout)
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">begin</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Begin a global transaction, and point out the timeout(use default transaction name)
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">begin</span><span class="hljs-params">(<span class="hljs-keyword">int</span> timeout)</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Begin a global transaction, and point out the transaction name and timeout.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">begin</span><span class="hljs-params">(<span class="hljs-keyword">int</span> timeout, String name)</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Commit globally
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">commit</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Rollback globally
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">rollback</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Get the status of transaction
     */</span>
    <span class="hljs-function">GlobalStatus <span class="hljs-title">getStatus</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> TransactionException</span>;

    <span class="hljs-comment">/**
     * Get the XID of transaction
     */</span>
    <span class="hljs-function">String <span class="hljs-title">getXid</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<h2>2.2 GlobalTransactionContext</h2>
<p>GlobalTransaction instance can be retrieved from GlobalTransactionContext:</p>
<pre><code class="language-java">
    <span class="hljs-comment">/**
     * Retrieve current global transaction instance, if it doesn't exist, create a new one.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> GlobalTransaction <span class="hljs-title">getCurrentOrCreate</span><span class="hljs-params">()</span> </span>{
        GlobalTransaction tx = getCurrent();
        <span class="hljs-keyword">if</span> (tx == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span> createNew();
        }
        <span class="hljs-keyword">return</span> tx;
    }

    <span class="hljs-comment">/**
     * Reload the global transaction identified by XID, the instance aren't allowed to begin transaction.
     * This API is usually used for centralized handling of failed transaction later.
     * For example, if it's time out to commit globally, the subsequent centralized processing steps are like this: reload the instance, from which retrieve the status, then recommit the transaction globally or not depends on the status value.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> GlobalTransaction <span class="hljs-title">reload</span><span class="hljs-params">(String xid)</span> <span class="hljs-keyword">throws</span> TransactionException </span>{
        GlobalTransaction tx = <span class="hljs-keyword">new</span> DefaultGlobalTransaction(xid, GlobalStatus.UnKnown, GlobalTransactionRole.Launcher) {
            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">begin</span><span class="hljs-params">(<span class="hljs-keyword">int</span> timeout, String name)</span> <span class="hljs-keyword">throws</span> TransactionException </span>{
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Never BEGIN on a RELOADED GlobalTransaction. "</span>);
            }
        };
        <span class="hljs-keyword">return</span> tx;
    }
</code></pre>
<h2>2.3 TransactionalTemplate</h2>
<p>TransactionalTemplate: Wrap a business service invoke into  a distributed transaction supported  service with preceding GlobalTransaction and GlobalTransactionContext API.</p>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TransactionalTemplate</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">execute</span><span class="hljs-params">(TransactionalExecutor business)</span> <span class="hljs-keyword">throws</span> TransactionalExecutor.ExecutionException </span>{

        <span class="hljs-comment">// 1. Get current global transaction instance or create a new one</span>
        GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();

        <span class="hljs-comment">// 2. Begin the global transaction</span>
        <span class="hljs-keyword">try</span> {
            tx.begin(business.timeout(), business.name());

        } <span class="hljs-keyword">catch</span> (TransactionException txe) {
            <span class="hljs-comment">// 2.1 Fail to begin</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> TransactionalExecutor.ExecutionException(tx, txe,
                TransactionalExecutor.Code.BeginFailure);

        }

        Object rs = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">try</span> {
            <span class="hljs-comment">// 3. invoke service</span>
            rs = business.execute();

        } <span class="hljs-keyword">catch</span> (Throwable ex) {

            <span class="hljs-comment">// Exception from business service invoke</span>
            <span class="hljs-keyword">try</span> {
                <span class="hljs-comment">// Rollback globally</span>
                tx.rollback();

                <span class="hljs-comment">// 3.1 Global rollback success, throw original business exception</span>
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> TransactionalExecutor.ExecutionException(tx, TransactionalExecutor.Code.RollbackDone, ex);

            } <span class="hljs-keyword">catch</span> (TransactionException txe) {
                <span class="hljs-comment">// 3.2 Global rollback failed</span>
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> TransactionalExecutor.ExecutionException(tx, txe,
                    TransactionalExecutor.Code.RollbackFailure, ex);

            }

        }

        <span class="hljs-comment">// 4. Commit globally</span>
        <span class="hljs-keyword">try</span> {
            tx.commit();

        } <span class="hljs-keyword">catch</span> (TransactionException txe) {
            <span class="hljs-comment">// 4.1 Global commit failed</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> TransactionalExecutor.ExecutionException(tx, txe,
                TransactionalExecutor.Code.CommitFailure);

        }
        <span class="hljs-keyword">return</span> rs;
    }

}
</code></pre>
<p>The exception of template method: ExecutionException</p>
<pre><code>    class ExecutionException extends Exception {

        // Transaction instance threw exception
        private GlobalTransaction transaction;

        // Exception code:
        // BeginFailure(Fail to begin transaction)
        // CommitFailure(Fail to commit globally)
        // RollbackFailure(Fail to rollback globally)
        // RollbackDone(Global rollback success)
        private Code code;

        // Original exception triggered by rollback
        private Throwable originalException;
</code></pre>
<p>Outer calling logic try-catch the exception, and do something based on the exception code:</p>
<ul>
<li><strong>BeginFailure</strong> (Fail to begin transaction): getCause() gets the framework exception of begin transaction, getOriginalException() is null.</li>
<li><strong>CommitFailure</strong>(Fail to commit globally):  getCause() gets the framework exception of commit transaction, getOriginalException() is null.</li>
<li><strong>RollbackFailure</strong> (Fail to rollback globally)：getCause() gets the framework exception of rollback transaction，getOriginalException() gets the original exception of business invoke.</li>
<li><strong>RollbackDone</strong>(Global rollback success): getCause()  is null, getOriginalException() gets the original exception of business invoke.</li>
</ul>
<h1>3. Low-Level API</h1>
<h2>3.1 RootContext</h2>
<p>RootContext: It's responsible for maintaining XID during runtime of application.</p>
<pre><code class="language-java">    <span class="hljs-comment">/**
     * Get the global XID of the current running application
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">getXID</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> CONTEXT_HOLDER.get(KEY_XID);
    }

    <span class="hljs-comment">/**
     * Bind the global XID to the current application runtime
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">bind</span><span class="hljs-params">(String xid)</span> </span>{
        <span class="hljs-keyword">if</span> (LOGGER.isDebugEnabled()) {
            LOGGER.debug(<span class="hljs-string">"bind "</span> + xid);
        }
        CONTEXT_HOLDER.put(KEY_XID, xid);
    }

    <span class="hljs-comment">/**
     * Unbind the global XID from the current application runtime, and return XID
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title">unbind</span><span class="hljs-params">()</span> </span>{
        String xid = CONTEXT_HOLDER.remove(KEY_XID);
        <span class="hljs-keyword">if</span> (LOGGER.isDebugEnabled()) {
            LOGGER.debug(<span class="hljs-string">"unbind "</span> + xid);
        }
        <span class="hljs-keyword">return</span> xid;
    }

    <span class="hljs-comment">/**
     * Check if the current application runtime is in the global transaction context
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">inGlobalTransaction</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> CONTEXT_HOLDER.get(KEY_XID) != <span class="hljs-keyword">null</span>;
    }
</code></pre>
<p>The implementation of High-Level API is based on maintaining XID in the RootContext.</p>
<p>Whether or not the operation of the current running application is in a global transaction context, just check if there is an XID in the RootContext.</p>
<p>The default implementation of RootContext is based on ThreadLocal, which is the XID is in the context of current thread.</p>
<p>Two classic scenes of Low-Level API :</p>
<h3>1. The propagation of transaction context by remote invoke</h3>
<p>Retrieve current XID by remote invoke:</p>
<pre><code class="language-java">String xid = RootContext.getXID();
</code></pre>
<p>Propagating the XID to the provider of service by RPC, bind the XID to current RootContext before executing the business logic of provider.</p>
<pre><code class="language-java">RootContext.bind(rpcXid);
</code></pre>
<h3>2. Pause and recover of transaction</h3>
<p>In a global transaction, if some business logic shouldn't be in the scope of the global transaction, unbind XID before invoke it.</p>
<pre><code class="language-java">String unbindXid = RootContext.unbind();
</code></pre>
<p>Rebind the XID back after the execution of related business logic to achieve recovering the global transaction.</p>
<pre><code class="language-java">RootContext.bind(unbindXid);
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="//img.alicdn.com/tfs/TB1dGrSwVT7gK0jSZFpXXaTkpXa-4802-1285.png"/><p class="docsite-power">website powered by docsite</p><div class="cols-container"><div class="col col-12"><h3>Vision</h3><p>Seata is an Alibaba open source distributed transaction solution that delivers high performance and easy to use distributed transaction services under a microservices architecture.</p></div><div class="col col-6"><dl><dt>Documentation</dt><dd><a href="/en-us/docs/overview/what-is-seata.html" target="_self">What is Seata?</a></dd><dd><a href="/en-us/docs/user/quickstart.html" target="_self">Quick Start</a></dd><dd><a href="https://github.com/seata/seata.github.io/issues/new" target="_self">Report a doc issue</a></dd><dd><a href="https://github.com/seata/seata.github.io" target="_self">Edit This Page on GitHub</a></dd></dl></div><div class="col col-6"><dl><dt>Resources</dt><dd><a href="/en-us/blog/index.html" target="_self">Blog</a></dd><dd><a href="/en-us/community/index.html" target="_self">Community</a></dd></dl></div></div><div class="copyright"><span>Copyright © 2019 Seata</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '';
  </script>
	<script src="/build/documentation.js"></script>
	<script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?104e73ef0c18b416b27abb23757ed8ee";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
    </script>
</body>
</html>
